#include <iostream>

using namespace std;

// 自定义非法输入异常
struct IllegalException : public exception {
    const char *what() const throw() override {
        return "C++ Exception";
    }
};

class Date {
public:
    static int const days[];

    // 空参构造器
    Date();

    // 构造函数
    Date(int newYear, int newMonth, int newDay);

    // 设置日期
    void setDate(int, int, int);

    // 展示日期
    void showDate() const;

    // 设置年
    void setYear(int newYear);

    // 设置月
    void setMonth(int newMonth);

    // 设置日
    void setDay(int newDay);

    // 判断输入的年是否合法
    static bool is_Year(int newYear);

    // 判断是否为闰年
    bool is_Leap_Year() const;

    // 判断是否为月底
    bool is_end_Of_Month() const;

    // 增加天数
    void add(int day);

    // 减少天数
    void reduce(int day);

    // 析构函数
    ~Date() {
        std::cout << "Bye!" << std::endl;
    };
private:
    int Year{}, Month{}, Day{};
};

Date::Date() {
    Year = 1000;
    Month = 1;
    Day = 1;
}

Date::Date(int newYear, int newMonth, int newDay) {
    Date::setDate(newYear, newMonth, newDay);
}

bool Date::is_Leap_Year() const {
    if ((Year % 4 == 0 && Year % 100 != 0) || (Year % 400 == 0)) return true;
    else return false;
}


bool Date::is_Year(int newYear) {
    int count = 0;
    for (int i = 0; newYear > 1; i++) {
        newYear /= 10;
        count++;
    }
    if (count == 4) return true;
    else return false;
}


void Date::showDate() const {
    std::cout << Year << "-" << Month << "-" << Day << std::endl;
}

void Date::setYear(int newYear) {
    try {
        if (is_Year(newYear)) {
            Year = newYear;
        } else {
            Year = 0;
            throw IllegalException();
        }
    } catch (IllegalException &e) {
        cout << "Illegal Year!" << endl;
    }
}

void Date::setMonth(int newMonth) {
    try {
        if (newMonth > 0 && newMonth <= 12) {
            Month = newMonth;
        } else {
            Month = 0;
            throw IllegalException();
        }
    } catch (IllegalException &e) {
        cout << "Illegal Month!" << endl;
    }
}

void Date::setDay(int newDay) {
    try {
        if (Month == 2 && (is_Leap_Year())) {
            Day = 29;
        } else if (newDay > 0 && newDay <= days[Month]) {
            Day = newDay;
        } else {
            Day = 0;
            throw IllegalException();
        }
    } catch (IllegalException &e) {
        cout << "Illegal Day!" << endl;
    }
}

void Date::setDate(int newYear, int newMonth, int newDay) {
    Date::setYear(newYear);
    Date::setMonth(newMonth);
    Date::setDay(newDay);
}

// 常量数组，定义每个月的天数
const int Date::days[13] = {0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};

bool Date::is_end_Of_Month() const {
    if (Month == 2 && is_Leap_Year()) {
        return Day == 29;
    } else {
        return Day == days[Month];
    }
}

void Date::add(int day) {
    for (int i = 0; i < day; ++i) {
        if (is_end_Of_Month() && Month == 12) {
            Year++;
            Month = 1;
            Day = 1;
        } else if (is_end_Of_Month()) {
            Month++;
            Day = 1;
        } else {
            Day++;
        }
    }
}

void Date::reduce(int day) {
    for (int i = 0; i < day; ++i) {
        if (Day == 1) {
            if (Month == 1) {
                Year--;
                Month = 12;
                Day = 31;
            } else if (Month == 3) {
                Day = is_Leap_Year() ? 29 : 28;
                Month = 2;
            } else
                Day = days[--Month];
        } else {
            Day--;
        }
    }
}

int main() {
    Date date(2002, 12, 1); // 定义对象date，调用构造函数
    date.showDate();
    date.add(180); // 增加180天
    date.showDate();
    date.reduce(50); // 减少50天
    date.showDate();
    return 0;
}
